﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;

namespace Cloak.Collections
{
	/// <summary>
	/// Extension methods for converting collections to observable collections
	/// </summary>
	public static class ObservableCollectionConversionExtensions
	{
		/// <summary>
		/// Creates an observable collection containing the items in the specified sequence
		/// </summary>
		/// <typeparam name="T">The type of item in the sequence</typeparam>
		/// <param name="source">The sequence whose items will be copied to the observable collection</param>
		/// <returns>An observable collection containing the items in the specified sequence</returns>
		public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> source)
		{
			Contract.Requires(source != null);

			return new ObservableCollection<T>(source);
		}

		/// <summary>
		/// Creates a read-only observable collection containing the items in the specified collection
		/// </summary>
		/// <typeparam name="T">The type of item in the collection</typeparam>
		/// <param name="source">The collection whose items will be copied to the read-only observable collection</param>
		/// <returns>A read-only observable collection containing the items in the specified sequence</returns>
		public static ReadOnlyObservableCollection<T> ToReadOnlyObservableCollection<T>(this ObservableCollection<T> source)
		{
			Contract.Requires(source != null);

			return new ReadOnlyObservableCollection<T>(source);
		}

		/// <summary>
		/// Creates a read-only observable collection containing the items in the specified sequence
		/// </summary>
		/// <typeparam name="T">The type of item in the sequence</typeparam>
		/// <param name="source">The sequence whose items will be copied to the read-only observable collection</param>
		/// <returns>A read-only observable collection containing the items in the specified sequence</returns>
		public static ReadOnlyObservableCollection<T> ToReadOnlyObservableCollection<T>(this IEnumerable<T> source)
		{
			Contract.Requires(source != null);

			return source.ToObservableCollection().ToReadOnlyObservableCollection();
		}

		/// <summary>
		/// Adds the items in the specified sequence to the observable collection
		/// </summary>
		/// <typeparam name="T">The type of item in the sequence</typeparam>
		/// <param name="source">The collection to which the items in the specified sequence will be added</param>
		/// <param name="items">The sequence containing the items to add to the specified collection</param>
		public static void AddRange<T>(this ObservableCollection<T> source, IEnumerable<T> items)
		{
			Contract.Requires(source != null);
			Contract.Requires(items != null);

			foreach(var item in items)
			{
				source.Add(item);
			}
		}
	}
}